onAppReady(function() {
	var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
	var IDBCursor = window.IDBCursor || window.webkitIDBCursor || window.mozIDBCursor;
	var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.mozIDBTransaction;
	// Database Object
	var db;
	
	// DB
	var DB_NAME = "offline-feed-reader7";
	// フィードエントリを格納するオブジェクトストアの名称
	var FEED_ENTRY_STORE = "FeedEntry7";
	
	// オブジェクトストアを再作成する
	function recreateObjectStore(db, storeName, createOpts) {
		var storeNames = db.objectStoreNames;
		// オブジェクトストアが存在すれば削除
		for (var i = 0, n = storeNames.length; i < n; i++) {
			if (storeNames[i] === storeName) {
				db.deleteObjectStore(storeName);
			}
		}
		db.createObjectStore(storeName, createOpts);
	}
	// DBのマイグレーション操作を保持する
	var DB_MIGRATION_OPS = [
		// Version 0
		function(db) {
			// URLをキーとしてエントリを保存するオブジェクトストアを作成
			recreateObjectStore(db, FEED_ENTRY_STORE, {
				keyPath: "url"
			});
		}
	];
	
	/**
	 * open IndexedDB
	 * @param callback callback when success open IndexedDB.
	 */
	function openIndexedDB(callback) {
		// 非同期でDBをオープン
		var req = indexedDB.open(DB_NAME);
		req.onsuccess = function(event) {
			db = req.result;
			var currentVersion = db.version || 0;
			var latestVersion = DB_MIGRATION_OPS.length;
			// 現在のバージョンと最新バージョンの間に差異があったら、
			// マイグレーション操作を順に実行
			if (currentVersion != latestVersion) {
				// バージョンをセットして
				db.setVersion(latestVersion).onsuccess = function(event) {
					// 順に呼び出し
					for (var i = currentVersion; i < latestVersion; i++) {
						DB_MIGRATION_OPS[i](db);
					}
					// migration finished!
					typeof callback == "function" && callback();
				};
			} else {
				// database opened successfully
				typeof callback == "function" && callback();
			}
		}
		req.onerror = function(event) {
			
		}
	}
	
	/**
	 * set feed entry to IndexedDB
	 * @param entries {Array} array of entry
	 * @param callback {Function} callback when all entry was saved.
	 */
	function storeFeedEntries(entries, callback) {
		
		// get feed from web
			
		var putSucceeded = 0;
		for (var i = 0, n = entries.length; i < n; i++) {
			var entry = entries[i];
//			alert(dump(entry));
			
			var feed = new google.feeds.Feed(entry.url);
			feed.setNumEntries(10);
			feed.load(function(result) {
				var storedata = {};
				if (!result.error) {
					storedata = result.feed;
					storedata.url = result.feed.feedUrl;
				} else {
				}
				// begin transaction
				var tx = db.transaction(FEED_ENTRY_STORE, IDBTransaction.READ_WRITE);
				// get object store
				var feedEntryStore = tx.objectStore(FEED_ENTRY_STORE);
				// save entry
				var putReq = feedEntryStore.put(storedata);
				putReq.onsuccess = function() {
					putSucceeded++;
					// all feeds are stored
					if (putSucceeded === n) {
						typeof callback == "function" && callback();
					}
				};
			});
		}
	}
	
	/**
	 * serch feed entry from IndexedDB
	 * @param query {Object} query（このサンプルでは使っていません）
	 * @param callback {Function} callback 引数にエントリの配列を取ります。
	 */
	function searchFeedEntries(query, callback) {
		var results = [];
		// このサンプルでは、全部のフィードをIDBから読み出す
		var tx = db.transaction(FEED_ENTRY_STORE, IDBTransaction.READ_ONLY);
		var feedEntryStore = tx.objectStore(FEED_ENTRY_STORE);
		var curReq = feedEntryStore.openCursor();
		curReq.onsuccess = function() {
			var cursor = curReq.result;
			// maybe end of cursor 
			if (!cursor) {
				typeof callback == "function" && callback(results);
				return;
			}
			var entry = cursor.value;
			results.push(entry);
			cursor.continue();
		};
	}
	
	// Feed Entries
	var feedEntries = [
		{
			url: "http://www.publickey1.jp/atom.xml?1",
			title: "Public Key",
		},
		{
			url: "http://mtl.recruit.co.jp/blog/index.xml",
			title: "Media Technology Lab.",
		},
		{
			url: "http://feeds.feedburner.com/gorime",
			title: "gori.me",
		},
		{
			url: "http://blog.hiroshitasaka.jp/index.rdf",
			title: "田坂広志 公式ブログ「新しい風」",
		},
	];
	
	
	
	
	// Open IDB
	openIndexedDB(function() {
		
		// save feed entry
		google.setOnLoadCallback(function() {
			storeFeedEntries(feedEntries, function() {
				// search feed entry from IDB
				searchFeedEntries({}, function(feeds) {
					// show list
					var listBody = $("#feedList > tbody");
					for (var i = 0, n = feeds.length; i < n; i++) {
						var feed = feeds[i];
						var row = $("<tr/>");
						$("<td/>").text(feed.title).appendTo(row);
						$("<td/>").text(feed.url).appendTo(row);
						listBody.append(row);
						
						// FeedEntry
				        var container = document.getElementById("feed");
						var a = document.createElement("a");
						a.href = feed.link;
				        a.appendChild(document.createTextNode(feed.title));
				        var h1 = document.createElement("h1");
				        h1.appendChild(a);
				        container.appendChild(h1);
				        if (feed.entries.length) {
				            var ul = document.createElement("ul");
				            for (var j = 0; j < feed.entries.length; j++) {
				                var entry = feed.entries[j];
								
								var a = document.createElement("a");
								a.href = entry.link;
					            a.appendChild(document.createTextNode(entry.title));
					            var li = document.createElement("li");
					            li.appendChild(a);
					            li.appendChild(document.createElement("br"));
								var span = document.createElement("span");
								span.class = "content";
					            span.appendChild(document.createTextNode(entry.contentSnippet));
					            li.appendChild(span);
								
					            ul.appendChild(li);
				            }
				            container.appendChild(ul);
				        }					
					}
				});
			});
		});
	});
});


google.load("feeds", "1");


// i48n
replaceI48N([
	"msg_url",
	"msg_title",
 ]);

function replaceI48N(names) {
	for(var i = 0; i < names.length; i ++) {
		var msg = document.getElementById(names[i]);
		msg.replaceChild(document.createTextNode(eval(names[i])), msg.firstChild);
	}
}


// Dumper
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	// The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { // Array/Hashes/Objects 
		for(var item in arr) {
			var value = arr[item];
			
			if(typeof(value) == 'object') { // If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { // Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}
